/*
 * Copyright (c) 田梓萱 2021-2022.
 * All Rights Reserved.
 * All codes are protected by China's regulations on the protection of computer software, and infringement must be investigated.
 * 版权所有 (c) 田梓萱 2021-2022.
 * 所有代码均受中国《计算机软件保护条例》保护，本项目已获得软著.
 */

package com.xcl.calculator.slice.QinQiCal;

import com.xcl.calculator.XLog;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

/**
 * The type Stackm.
 *
 * @param <T> the type parameter
 * @author Xcl
 * @date 2022 /1/3
 * @package com.xcl.calculator.slice.QinQiCal
 */
public class Stackm<T> {
    /**
     * The constant label.
     */
    private static final HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x00234, "Stackm");
    /**
     * The constant MAXSIZE.
     */
    private static final int MAXSIZE = 14;  /* 存储空间初始分配量 */
    /**
     * The Top.
     */
    private int top;    /* 栈顶指针 */
    /**
     * The Size.
     */
    private int size;   /* 栈的最大空间 */
    /**
     * The Stack.
     */
    private Object[] stack; /* 顺序栈 */

    /**
     * Instantiates a new Stackm.
     */
//创建栈
    Stackm() {
        try {
            this.size = MAXSIZE;
            this.stack = new Object[this.size];
            this.top = -1;
        } catch (Exception e) {
            XLog.error(label, e.getMessage());
        }
    }

    /**
     * Instantiates a new Stackm.
     *
     * @param sz the sz
     */
//创建自定义空间大小的栈
    public Stackm(int sz) {
        try {
            this.size = sz;
            this.stack = new Object[this.size];
            this.top = -1;
        } catch (Exception e) {
            XLog.error(label, e.getMessage());
        }
    }

    /**
     * Instantiates a new Stackm.
     *
     * @param item the item
     */
    public Stackm(Stackm item) {
        try {
            this.stack = new Object[item.size];
            this.top = item.top;
            for (int i = 0; i < item.StackLength(); ++i) this.stack[i] = item.stack[i];
            this.size = item.size;
        } catch (Exception e) {
            XLog.error(label, e.getMessage());
        }
    }

    /**
     * Clear stack.
     */
//清空栈
    void clearStack() {
        this.top = -1;
    }

    /**
     * Is empty boolean.
     *
     * @return the boolean
     */
//判断栈空
    boolean isEmpty() {
        return this.top == -1;
    }

    /**
     * Stack length int.
     *
     * @return the int
     */
//栈长
    private int StackLength() {
        return this.top + 1;
    }

    /**
     * 获取栈顶元素
     *
     * @return 栈顶元素 top
     */
    T getTop() {
        T result = null;
        if (this.top != -1) result = (T) this.stack[this.top];
        return result;
    }

    /**
     * 入栈操作
     *
     * @param newElem 等待入栈的元素
     */
    void push(T newElem) {
        try {
            if (this.top == MAXSIZE) {
                Object[] temp = this.stack;
                // 如果栈满，则创建空间为当前栈空间两倍的栈
                this.stack = new Object[this.stack.length * 2];
                System.arraycopy(temp, 0, this.stack, 0, temp.length);
            }
            this.stack[++this.top] = newElem;
        } catch (Exception e) {
            XLog.error(label, e.getMessage());
        }
    }

    /**
     * 出栈操作
     *
     * @return 栈顶元素 t
     */
    T pop() {
        if (this.isEmpty()) return null;
        T elem = this.getTop();
        this.stack[this.top--] = null;
        return elem;
    }

    /**
     * Stack traverse.
     */
//栈的遍历
    public void StackTraverse() {
        try {
            while (this.top != -1) {
                System.out.print(this.stack[this.top]);
                --this.top;
            }
        } catch (Exception e) {
            XLog.error(label, e.getMessage());
        }
    }
}